#!C:\work\Python27\python.exe
# -*- coding: utf-8 -*-

from openpyxl.workbook import Workbook
from openpyxl.reader.excel import load_workbook

import Tkinter
from Tkinter import *
import tkFileDialog as fd

import os

import time
import datetime

from copy import deepcopy

##from collections import defaultdict

from SPARQLWrapper import SPARQLWrapper, JSON, ASK, POST, GET, N3, XML


def main():
    ohjelmaLoppuu = False
    ikkuna = Tkinter.Tk()
    ikkuna.withdraw()  #Piilottaa ikkunan(GUI)
    d = fd.askopenfilenames(title="Avaa tiedosto") #Näyttää "avaa-tiedosto"-ikkunan
    if(d == None or d == ""): #Jos "avaa-tiedosto"-ikkunassa painaa näppäintä "Cancel", ohjelma loppuu
        print "Ohjelma suljetaan"
        ohjelmaLoppuu = True
##    d = encoder(d)
    d = str(d)
    d = ikkuna.tk.splitlist(d)
    laskuri = 0

    while(ohjelmaLoppuu == False):
        if(laskuri >= len(d)):
            ohjelmaLoppuu = True
            break

        tiedostopolku = d[laskuri]
        tiedostopolku = tiedostopolku.decode('utf-8')

        index = tiedostopolku.rfind("/", 0, len(tiedostopolku))
        tiedosto = tiedostopolku[index+1:]
        print tiedosto

        wb = load_workbook(tiedostopolku)

        tanaan = datetime.date.today() #Tämänhetkinen päiväys

        #luo tarvittaessa uuden "xmldocs"-kansion uudella päivämäärällä
        if not os.access("xmldocs\\"+str(tanaan), os.F_OK):
            os.makedirs("xmldocs\\"+str(tanaan))
##        if(os.path.exists("xmldocs\\"+str(tanaan)) == False):
##            os.makedirs("xmldocs\\"+str(tanaan))

        #luo uuden Validointiraportti-tiedoston juoksevalla numerolla
        numero = 1
        uusiTiedostoOk = False
        while(uusiTiedostoOk == False):
            if(os.path.isfile("xmldocs\\"+str(tanaan)+"\\"+tiedosto+"_"+str(tanaan)+"_("+str(numero)+").xml") == False):
                handle = open("xmldocs\\"+str(tanaan)+"\\"+tiedosto+"_"+str(tanaan)+"_("+str(numero)+").xml", "a")
                uusiTiedostoOk = True
            else:
               numero += 1

        valilehdet(wb, tiedosto, handle)

        handle.close() #sulkee tiedoston

        os.startfile("xmldocs\\"+str(tanaan)+"\\"+tiedosto+"_"+str(tanaan)+"_("+str(numero)+").xml") #käynnistää luodun tiedoston

        laskuri += 1

#Käy läpi välilehtiä
def valilehdet(wb, tiedosto, handle):
    #Aloittaa xml-dokumentin:
    ekaValilehti = wb.worksheets[0]
    libraryName = ekaValilehti.cell(row = 0, column = 0).value
    xmlLisays = ("<?xml version='1.0' encoding='UTF-8'?>\n"
                 "<!--  "+tiedosto+"  -->\n"
                 "<BusinessDocumentLibrary>\n")
    xmldoc(xmlLisays, handle)
    xmlLisays = ("<LibraryName>"+libraryName+"</LibraryName>\n"
                )
    xmldoc(xmlLisays, handle)

    stack = []
    valilehti = 0
    valilehtiaYhteensa = len(wb.worksheets)

    while(valilehti < valilehtiaYhteensa):
        ws = wb.worksheets[valilehti]
        valilehdenNimi = str(ws)
        valilehdenNimi = valilehdenNimi.decode('utf-8')

        index1 = valilehdenNimi.find('"', 0, len(valilehdenNimi))
        index2 = valilehdenNimi.rfind('"', 0, len(valilehdenNimi))
        valilehdenNimi = valilehdenNimi[index1+1:index2]

        valilehdenNimi = valilehdenNimi.capitalize()

        print valilehdenNimi

        rivi = ekatarkistus(ws)
        if(rivi == -1):
            valilehti += 1
        else:
            dn = ws.cell(row = 0, column = 0).value
            dn = dn.lower()
            dn = dn.capitalize()

            dl = unicode(dn)
            
            dn = valitpois(dn)
            dn = aakkosiksi(dn)
            dn = unicode(dn)
            
            dt = dokunimenTarkistus(ws)
            dt = unicode(dt)
##            dt = str(dt)

            
            xmlLisays = ("<BusinessDocument>\n"
                         "      <DocumentName>"+dn+"</DocumentName>\n"
                         "      <DocumentLabel>"+dl+"</DocumentLabel>\n"
                         "      <DocumentType>"+dt+"</DocumentType>\n"
                         "      <DocumentDefinition>"+unicode(dokumaarityksenTarkistus(ws))+"</DocumentDefinition>"
                         )
            xmldoc(xmlLisays, handle)

            tokatarkistus(rivi, ws, stack, handle, dn)

            xmlLisays = ("</BusinessDocument>")
            xmldoc(xmlLisays, handle)

            valilehti += 1

    #Lopettaa xml-dokumentin:
    xmlLisays = ("</BusinessDocumentLibrary>\n"
                 "<!--  Generated by SARVI-palvelu  -->")
    xmldoc(xmlLisays, handle)
    print "Valmis"

##Hakee dokumentin määrityksen.
def dokunimenTarkistus(ws):
    return ws.cell(row = 2, column = 0).value

##Hakee dokumentin määrityksen.
def dokumaarityksenTarkistus(ws):
    palauta = ws.cell(row = 2, column = 8).value
    return str(palauta)

##Lisää html-koodia tiedostoon.
def xmldoc(xmlLisays, handle):
    xmldoc = []
    xmldoc.append(xmlLisays)
    handle.write((" ".join(xmldoc))+"\n")

##Tutkii löytyykö välilehdestä saraketta: "Asiakirjarakenteet".
def ekatarkistus(ws):
    valmis = False
    etsittava = "Asiakirjarakenteet"
    ruutu = None
    rivi = 0
    loytyi = False

    while(valmis == False):
        ruutu = ws.cell(row = rivi, column = 0)
        if(ruutu.value == etsittava):
            loytyi = True
            valmis = True
        else:
            if(rivi < 18000):
                rivi += 1
            else:
                valmis = True
    if(loytyi == True):
        rivi += 1
        return rivi
    else:
        return -1

##Testaa onko annettu rivi tyhjä
def tyhjanRivinHaku(ws, rivi):
    tyhjarivi = True
    sarake = 0
    tiedonesitysmuoto = tiedonEsitysmuotoTarkistus(ws)
    for sarake in range(0, tiedonesitysmuoto):
        if(ws.cell(row = rivi, column = sarake).value != None):
            tyhjarivi = False
        sarake += 1

    return tyhjarivi

##Etsii taulukosta tietyt kentät
def tokatarkistus(rivi, ws, stack, handle, dn):
    sarake = 0
    ruutu = ws.cell(row = rivi, column = sarake)
    lopetus = viimeinenRiviTaulukossa(ws)
    etsittava = "TK "
    edellinensarake = 0
    stack = []
    tesStack = []

    ohitettavatLista = [u"Otsikko, vain näyttömuotoon",
                        u"Otsikko",
                        u"Otsikko vain näyttömuotoon",
                        u"otsikko, vain näyttömuotoon",
                        u"otsikko vain näyttömuotoon",
                        u"otsikko, vain näyttömuodossa",
                        u"Otsikko näyttömuotoon",
                        u"Otsikko, näyttömuotoon",
                        u"ei otsikkoa",
                        u"Tyhjä rivi, vain näyttömuotoon",
                        u"tyhjä rivi, vain näyttömuotoon",
                        u"tyhjä rivi vain näyttömuotoon",
                        u"Tyhjä rivi vain näyttömuotoon",
                        u"Tyhjä rivi näyttömuotoon",
                        u"Vain näyttömuotoon",
                        u"Tyhjä rivi",
                        u"tyhjä rivi",
                        u"tyhjä rivi ",
                        ]

    for rivi in range(rivi, lopetus + 1):
        sarake = 0
        while(ws.cell(row = rivi, column = sarake).value == None and sarake < 7):
            sarake+=1
        ruutu = ws.cell(row = rivi, column = sarake)
        for count in range(sarake,edellinensarake + 1):
            if(len(stack) > 0):
                stack.pop()
                tesStack.pop()
        if(len(stack)> 0):
            ollaantkssa = stack[len(stack)-1]
            ollaantestkssa = tesStack[len(stack)-1]
        else:
            ollaantkssa = None
            ollaantestkssa = None

        maaritelmasarake = maaritelmaTarkistus(ws)
        esimerkkisarake = esimerkkiTarkistus(ws)
        tiedonesitysmuotosarake = tiedonEsitysmuotoTarkistus(ws)
        huomautussarake = huomautusTarkistus(ws)
 #       dokumentaatiosarake = dokumentaatioTarkistus(ws)
        toistuvasarake = toistuvaTarkistus(ws)
        pakollinensarake = pakollinenTarkistus(ws)

        maaritelma = ws.cell(row = rivi, column = maaritelmasarake).value
        esimerkki = ws.cell(row = rivi, column = esimerkkisarake).value
        tesruutu = ws.cell(row = rivi, column = tiedonesitysmuotosarake).value
        huomautus = ws.cell(row = rivi, column = huomautussarake).value
#        dokumentaatio = ws.cell(row = rivi, column = dokumentaatiosarake).value
        toistuva = ws.cell(row = rivi, column = toistuvasarake).value
        pakollinen = ws.cell(row = rivi, column = pakollinensarake).value
        
        stack.append(ruutu.value)
        tesStack.append(tesruutu)
        
        etsitaan = ruutu.value
        if((etsitaan in ohitettavatLista) == True):
            etsitaan = None
        else:
            etsitaan = ruutu.value
        if((ollaantkssa in ohitettavatLista) == True):
            mista = None
            tesMista = None
        else:
            mista = ollaantkssa
            tesMista = ollaantestkssa

        if(etsitaan != None):
            if(("llekirjo" in etsitaan) == False):
                xmldoclisaaja(etsitaan, tesMista, mista, tesruutu, maaritelma, esimerkki, huomautus, toistuva, pakollinen, handle, sarake, stack, ws, rivi,dn)

        rivi += 1
        edellinensarake = sarake

##Lisää xml-tiedostoon "BusinessInformationEntity"-luokkia
def xmldoclisaaja(etsitaan, tesMista, mista, tesruutu, maaritelma, esimerkki, huomautus, toistuva, pakollinen, handle, sarake, stack, ws, rivi,dn):
    asiakirjanNimi = dn#ws.cell(row = 0, column = 0).value
    originalEtsitaan = deepcopy(etsitaan)
##    originalTesruutu = deepcopy(tesruutu)
##    originalMista = deepcopy(mista)
####    if(originalTesruutu != None):
####        originalTesruutu = originalTesruutu.replace('TK ', '', 1)
##    if(etsitaan != None and (type(etsitaan) is float) == False):
##        etsitaan = etsitaan.replace('TK ', '', 1)
##        etsitaan = aakkosiksi(etsitaan)
##        etsitaan = valitpois(etsitaan)
##    if(mista != None and (type(etsitaan) is float) == False):
##        mista = mista.replace('TK ', '', 1)
##        mista = aakkosiksi(mista)
##        mista = valitpois(mista)
##    if(tesruutu != None and (type(etsitaan) is float) == False):
##        tesruutu = tesruutu.replace('TK ', '', 1)
##        tesruutu = aakkosiksi(tesruutu)
##        tesruutu = valitpois(tesruutu)
    if(asiakirjanNimi != None and (type(asiakirjanNimi) is float) == False):
        asiakirjanNimi = aakkosiksi(asiakirjanNimi)
        asiakirjanNimi = valitpois(asiakirjanNimi)

    ylihypattavat = [u"yksityishenkilö",
                     u"ammattihenkilö",
                     u"rooli",
                     u"osoite",
                     u"organisaatio"]
    varaStack = []
    stackKopio = deepcopy(stack)
    for i in range(0, len(stack)):
        if(len(stack) != 0):
            varaStack.append(stackKopio.pop())

 #   if(tesruutu != None):
 #       representationTerm = tesruutu.replace('TK ', '', 1)
 
    # Tiedon esitysmuoto

    representationTerm = "VIRHE"
    associatedObjectClassTerm = "VIRHE"
    entryType = "VIRHE"
    
##    if(tesMista != None):
##        mista = tesMista.replace('TK ', '', 1)
##    print etsitaan+"-"+str(mista)+"-"+str(tesMista)
    if(onkoLuokka(etsitaan) == True or onkoASBIE(etsitaan, mista) == True or tesruutu != None and onkoLuokka(tesruutu.replace('TK ', '', 1))):
        if(tesruutu != None):
            etsitaan = tesruutu.replace('TK ', '', 1)
        entryType = "ASBIE"
        associatedObjectClassTerm = valitpois(etsitaan)
        associatedObjectClassTerm = aakkosiksi(associatedObjectClassTerm) 
    else:
        if(tesruutu != None):
            representationTerm = tietotyyppi(tesruutu)
        else:
            mita = u"hasRepresentationTerm"
            tagName = "uri"
            entryType = "BBIE"
            if(tesMista != None):
                tesMista = tesMista.replace('TK ', '', 1)
            if(onkoLuokka(mista) == True or onkoMistaASBIE(mista, etsitaan) == True):
                representationTerm = sisallonPaivitys(etsitaan, mista, mita, tagName, entryType)
                if(representationTerm != None):
                    index = representationTerm.rfind(u'#', 0, len(representationTerm))
                    representationTerm = representationTerm[index+1:]
            elif(onkoLuokka(mista) == False and tesMista != None and onkoLuokka(tesMista) == True):
                representationTerm = sisallonPaivitys(etsitaan, tesMista, mita, tagName, entryType)
                if(representationTerm != None):
                    index = representationTerm.rfind(u'#', 0, len(representationTerm))
                    representationTerm = representationTerm[index+1:]
            else:#if(onkoLuokka(mista) == False and tesMista == None):
                representationTerm = "VIRHE"

    #AssociatedObjectClassTerm:
#    if(mista != None):
  
        
#    if(associatedObjectClassTerm == None):
#        associatedObjectClassTerm = "VIRHE"

    
##    print originalEtsitaan

    #ASBIE-DictionaryEntryName:
    asdictionaryEntryName = ""
    asbieStack = deepcopy(varaStack)
    while(len(asbieStack) != 0):
        asdictionaryEntryName = asdictionaryEntryName+valitpois(asbieStack.pop())+"."
    if(asdictionaryEntryName != None):
        asdictionaryEntryName = asdictionaryEntryName+associatedObjectClassTerm
    asdictionaryEntryName = asdictionaryEntryName.rstrip(".")
    asdictionaryEntryName = aakkosiksi(asdictionaryEntryName)
    

    #ABIE-DictionaryEntryName:
    abdictionaryEntryName = ""
    abieStack = deepcopy(varaStack)
    while(len(abieStack) != 0):
        abdictionaryEntryName = abdictionaryEntryName+valitpois(abieStack.pop())+"."
    abdictionaryEntryName = abdictionaryEntryName.rstrip(".")
    abdictionaryEntryName = aakkosiksi(abdictionaryEntryName)
##    if(abdictionaryEntryName != None):
##        abdictionaryEntryName = abdictionaryEntryName+etsitaan

    #BBIE-DictionaryEntryName:
    bbdictionaryEntryName = ""
    bbieStack = deepcopy(varaStack)
    while(len(bbieStack) != 0):
        bbdictionaryEntryName = bbdictionaryEntryName+valitpois(bbieStack.pop())+"."
    if(bbdictionaryEntryName != None and representationTerm != None):
        bbdictionaryEntryName = bbdictionaryEntryName+representationTerm
    bbdictionaryEntryName = bbdictionaryEntryName.rstrip(".")
    bbdictionaryEntryName = aakkosiksi(bbdictionaryEntryName)

    #ObjectClassTerm:
    objectClassTerm = "VIRHE"
##    if(tesMista != None):
##        objectClassTerm = valitpois(tesMista)
##        objectClassTerm = aakkosiksi(objectClassTerm)
##        objectClassTerm = valitpois(mista)
##        objectClassTerm = aakkosiksi(mista)

    abobjectClassTermQualifier = None
    abobjectClassTerm = "VIRHE"
    asobjectClassTerm = "VIRHE"
##    bbobjectClassTerm = "VIRHE"

    if(mista == None):
        #ASBIEobjectClassTerm
        asobjectClassTerm = asiakirjanNimi
        #ABIEobjectClassTerm
        abobjectClassTerm = associatedObjectClassTerm
        #BBIEobjectClassTerm:
        bbobjectClassTerm = asiakirjanNimi
##        bbobjectClassTerm = ""
##        bbieStack2 = deepcopy(varaStack)
##        while(len(bbieStack2) != 0):
##            bbobjectClassTerm = bbobjectClassTerm+valitpois(bbieStack2.pop())+"."
##        bbobjectClassTerm = bbobjectClassTerm.rstrip(".")
##        bbobjectClassTerm = aakkosiksi(bbobjectClassTerm)
        
##        #BBIEobjectClassTerm
##        index = bbdictionaryEntryName.rfind(u'.', 0, len(bbdictionaryEntryName))
##        bbobjectClassTerm = bbobjectClassTerm[:index]
    elif(mista != None):
        #ABIEobjectClassTerm
        abobjectClassTerm = deepcopy(abdictionaryEntryName)
        #ASBIEassociatedObjectClassTerm
        index = asdictionaryEntryName.rfind(u'.', 0, len(asdictionaryEntryName))
        associatedObjectClassTerm = asdictionaryEntryName[:index]
        #ASBIEObjectClassTerm+bbieObjectClassTerm
        index = associatedObjectClassTerm.rfind(u'.', 0, len(associatedObjectClassTerm))
        asobjectClassTerm = associatedObjectClassTerm[:index]
        #BBIEObjectClassTerm
        bbobjectClassTerm = ""
        bbieStack2 = deepcopy(varaStack)
        while(len(bbieStack2) != 0):
            bbobjectClassTerm = bbobjectClassTerm+valitpois(bbieStack2.pop())+"."
        bbobjectClassTerm = bbobjectClassTerm.rstrip(".")
        bbobjectClassTerm = aakkosiksi(bbobjectClassTerm)
        index = bbobjectClassTerm.rfind(u'.', 0, len(bbobjectClassTerm))
        bbobjectClassTerm = bbobjectClassTerm[:index]




##        abobjectClassTermQualifier = valitpois(originalEtsitaan)
##        abobjectClassTermQualifier = aakkosiksi(abobjectClassTerm)
##        if(abobjectClassTerm == abobjectClassTermQualifier):
##            abobjectClassTermQualifier == None

    #PropertyTerm:
    propertyTerm = "VIRHE"
    if(etsitaan != None):
        propertyTerm = valitpois(originalEtsitaan)
        propertyTerm = aakkosiksi(propertyTerm)
    else:
        propertyTerm = ""

    #BasedOnCoreComponent:

    basedOnCoreComponent = "VIRHE"
    tagName = "uri"
    
##    if(mista == None):
    mita = u"hasObjectClassTerm"
##    elif(mista != None):
##        mita = u"hasAssociatedObjectClass"
        

    if(onkoLuokka(etsitaan) == True or onkoASBIE(etsitaan,mista)):
        basedOnCoreComponent = sisallonPaivitys(etsitaan, None, mita, tagName, entryType)
        
    if(basedOnCoreComponent == None):
        basedOnCoreComponent = "VIRHE!"
        
    #Label:
    label = originalEtsitaan
    if(label == None):
        label = "VIRHE"

    #Example:
    if(esimerkki == None):
        mita = u"example"
        tagName = u"literal"
        esimerkki = sisallonPaivitys(etsitaan, mista, mita, tagName, entryType)
    example = esimerkki
    if(example != None):
        example = "  <Example>"+str(example)+"</Example>"
 
   #Definition:
    if(maaritelma == None):
        mita = u"definition"
        tagName = u"literal"
        maaritelma = sisallonPaivitys(etsitaan, mista, mita, tagName, entryType)
    definition = maaritelma
    if(definition != None):
        definition = "  <Definition>"+xmlSafe(str(definition))+"</Definition>"

    #MinOccurs:
    if(pakollinen == None):
        mita = u"minOccurs"
        tagName = u"literal"
        pakollinen = sisallonPaivitys(etsitaan, mista, mita, tagName, entryType)
    if(pakollinen == u"ei"):
        pakollinen = u"0"
    elif(pakollinen == u"kyllä"):
        pakollinen = u"1"
    minOccurs = pakollinen
    if(minOccurs != None):
       minOccurs = "  <MinOccurs>"+str(minOccurs)+"</MinOccurs>"

    #MaxOccurs:
    if(toistuva == None):
        mita = u"maxOccurs"
        tagName = u"literal"
        toistuva = sisallonPaivitys(etsitaan, mista, mita, tagName, entryType)
    if(toistuva == u"ei"):
        toistuva = u"1"
    elif(toistuva == u"kyllä"):
        toistuva = u"unbounded"
    maxOccurs = toistuva
    if(maxOccurs != None):
        maxOccurs = "  <MaxOccurs>"+str(maxOccurs)+"</MaxOccurs>"

    #Notice:
    if(huomautus == None):
        mita = u"notice"
        tagName = u"literal"
        huomautus = sisallonPaivitys(etsitaan, mista, mita, tagName, entryType)
    notice = huomautus
    if(notice != None):
        notice = "  <Notice>"+xmlSafe(str(notice))+"</Notice>"

    if(tesruutu != None):
        tesruutu = tesruutu.replace('TK ', '', 1)
    if(onkoLuokka(etsitaan) == True or onkoLuokka(tesruutu) == True or onkoASBIE(etsitaan,mista) == True):
        ##ASBIE:
##        print ""
##        print "ASBIE"
##        print "asdictionaryEntryName: "+str(asdictionaryEntryName)
##        print "objectClassTerm: "+str(objectClassTerm)
##        print "EntryType: ASBIE"
##        print "propertyTerm: "+str(propertyTerm)
##        print "AssociatedObjectClassTerm: "+str(associatedObjectClassTerm)
##        print "example: "+str(example)
##        print "definition: "+str(definition)
##        print "notice: "+str(notice)
##        print "minOccurs: "+str(minOccurs)
##        print "maxOccurs: "+str(maxOccurs)
        xmlLisays = ("<BusinessInformationEntity>\n"
                     "  <DictionaryEntryName>"+asdictionaryEntryName+"</DictionaryEntryName>\n"
                     "  <EntryType>ASBIE</EntryType>\n"
                     "  <ObjectClassTerm>"+asobjectClassTerm+"</ObjectClassTerm>\n"
                     "  <PropertyTerm>"+propertyTerm+"</PropertyTerm>\n"
                     "  <Label>"+label+"</Label>\n"
                     ""+("  <AssociatedObjectClassTerm>"+associatedObjectClassTerm+"</AssociatedObjectClassTerm>" if associatedObjectClassTerm != None else "")+"\n"
                     ""+(example if example != None else "")+"\n"
                     ""+(definition if definition != None else "")+"\n"
                     ""+(notice if notice != None else "")+"\n"
                     ""+(minOccurs if minOccurs != None else "")+"\n"
                     ""+(maxOccurs if maxOccurs != None else "")+"\n"
                     "</BusinessInformationEntity>\n"
                     "")
        xmldoc(xmlLisays, handle)
##        print ""
##        print "ABIE"
##        print "abdictionaryEntryName: "+str(abdictionaryEntryName)
##        print "objectClassTerm: "+str(objectClassTerm)
##        print "EntryType: ABIE"
        ##ABIE:
        xmlLisays = ("<BusinessInformationEntity>\n"
                     "  <DictionaryEntryName>"+abdictionaryEntryName+"</DictionaryEntryName>\n"
                     "  <EntryType>ABIE</EntryType>\n"
                     "  <ObjectClassTerm>"+abdictionaryEntryName+"</ObjectClassTerm>\n"
                     "  <Label>"+label+"</Label>\n"
                     "  <BasedOnCoreComponent>"+basedOnCoreComponent+"</BasedOnCoreComponent>\n"
                     "</BusinessInformationEntity>\n"
                     "")
        xmldoc(xmlLisays, handle)
    else:
##        print ""
##        print "BBIE"
##        print "bbdictionaryEntryName: "+str(bbdictionaryEntryName)
##        print "objectClassTerm: "+str(bbobjectClassTerm)
##        print "EntryType: BBIE"
##        print "propertyTerm: "+str(propertyTerm)
##        print "representationTerm: "+str(representationTerm)
##        print "example: "+str(example)
##        print "definition: "+str(definition)
##        print "notice: "+str(notice)
##        print "minOccurs: "+str(minOccurs)
##        print "maxOccurs: "+str(maxOccurs)
        ##BBIE:
        xmlLisays = ("<BusinessInformationEntity>\n"
                     ""+("  <DictionaryEntryName>"+bbdictionaryEntryName+"</DictionaryEntryName>" if bbdictionaryEntryName != None else "VIRHE")+"\n"
                     "  <EntryType>BBIE</EntryType>\n"
                     ""+("  <ObjectClassTerm>"+bbobjectClassTerm+"</ObjectClassTerm>" if bbobjectClassTerm != None else "bbobjectClassTerm : VIRHE")+"\n"
                     ""+("  <Label>"+label+"</Label>" if label != None else "VIRHE")+"\n"
                     ""+("  <PropertyTerm>"+propertyTerm+"</PropertyTerm>" if propertyTerm != None else "VIRHE")+"\n"
                     ""+("  <RepresentationTerm>"+representationTerm+"</RepresentationTerm>" if representationTerm != None else "representationTerm : VIRHE")+"\n"
                     ""+(example if example != None else "")+"\n"
                     ""+(definition if definition != None else "")+"\n"
                     ""+(notice if notice != None else "")+"\n"
                     ""+(minOccurs if minOccurs != None else "")+"\n"
                     ""+(maxOccurs if maxOccurs != None else "")+"\n"
                     "</BusinessInformationEntity>\n"
                     "")
        xmldoc(xmlLisays, handle)

#Oikean tietotyypin hakumetodi
def tietotyyppi(tesruutu):
    tesruutu = tesruutu.lower()
    
    dictionary = {u'€' : 'Maara',     
                  u'kyllä/ei' : 'Kytkin',
                  u'kytkin' : 'Kytkin',
                  u'päivämäärä' : 'Pvm',
                  u'pvm' : 'Pvm',
                  u'aika' : 'Aika',
                  u'arvo' : 'Arvo',
                  u'mitta' : 'Mitta',
                  u'tunnus' : 'Tunnus',
                  u'teksti' : 'Teksti',
                  u'koodi' : 'Koodi',
                  u'numero' : 'Numero',
                  u'lkm' : 'Lkm',
                  u'lukumäärä' : 'Lkm',
                  u'maara' : 'Maara',
                  u'prosentti' : 'Prosentti',
                  u'nimi' : 'Nimi',
                  }
    
    return dictionary.get(tesruutu, "Teksti")
        
##Muuntaa annetun sanan ääkköset unicode-koodiksi
def unicodeksi(string):
    if(string != None):
        string = string.replace(u'ä', '\u00E4')
        string = string.replace(u'Ä', '\u00C4')
        string = string.replace(u'ö', '\u00F6')
        string = string.replace(u'Ö', '\u00D6')
        return string

##Tarkistaa onko annettu kenttä luokka
def onkoLuokka(etsitaan):
    if(etsitaan == None):
        return False
    
    etsitaan = valinPoisto(etsitaan)#Poistaa ylimääräiset välilyönnit.
    etsitaan = sanaMuunnos(etsitaan)#Muuntaa annetun sanan ääkköset unicode-koodiksi.
        
    if((type(etsitaan) is float) == False):
        queryString = u'PREFIX ccts: <http://tikesos.fi/ccts#> \
                        PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \
                        PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \
                        ASK { ?a rdf:type ccts:ABIE . ?a rdfs:label ?str . FILTER (?str = "'+etsitaan+u'")}'

        sparql = SPARQLWrapper(u"http://sosmeta.fi:8080/openrdf-sesame/repositories/sosmeta")

        sparql.setQuery(queryString)
        sparql.setMethod(POST)
        sparql.setReturnFormat(XML)
        results = sparql.query().convert()

        for elem in results.getElementsByTagName(u'boolean'):
            child = elem.firstChild
            if child:
                if(child.nodeValue == u"true"):
                    return True
                else:
                    return False

def onkoASBIE(etsitaan, mista):
    if(etsitaan == None or mista == None):
        return False

    etsitaan = valinPoisto(etsitaan)#Poistaa ylimääräiset välilyönnit.
    etsitaan = sanaMuunnos(etsitaan)#Muuntaa annetun sanan ääkköset unicode-koodiksi.
    mista = valinPoisto(mista)#Poistaa ylimääräiset välilyönnit.
    mista = sanaMuunnos(mista)#Muuntaa annetun sanan ääkköset unicode-koodiksi.
        
    if((type(etsitaan) is float) == False):
        queryString = u"PREFIX ccts: <http://tikesos.fi/ccts#> \
                        PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \
                        PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \
                        ASK { ?a ccts:hasObjectClassTerm ?upper . \
                        ?upper rdfs:label ?mista . \
                        ?a rdf:type ccts:ASBIE . ?a rdfs:label ?str . FILTER (?str = '"+etsitaan+u"') \
                        FILTER (?mista = '"+mista+u"')}"

        sparql = SPARQLWrapper(u"http://sosmeta.fi:8080/openrdf-sesame/repositories/sosmeta")

        sparql.setQuery(queryString)
        sparql.setMethod(POST)
        sparql.setReturnFormat(XML)
        results = sparql.query().convert()

        for elem in results.getElementsByTagName(u'boolean'):
            child = elem.firstChild
            if child:
                if(child.nodeValue == u"true"):
                    return True
                else:
                    return False

def onkoMistaASBIE(mista,etsitaan):
    if(etsitaan == None or mista == None):
        return False

    etsitaan = valinPoisto(etsitaan)#Poistaa ylimääräiset välilyönnit.
    etsitaan = sanaMuunnos(etsitaan)#Muuntaa annetun sanan ääkköset unicode-koodiksi.
    mista = valinPoisto(mista)#Poistaa ylimääräiset välilyönnit.
    mista = sanaMuunnos(mista)#Muuntaa annetun sanan ääkköset unicode-koodiksi.
        
    if((type(etsitaan) is float) == False):
        queryString = u"PREFIX ccts: <http://tikesos.fi/ccts#> \
                        PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \
                        PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \
                        ASK { ?a ccts:hasObjectClassTerm ?oTerm . \
                        ?a rdfs:label ?str . \
                        ?b rdf:type ccts:ASBIE . ?b rdfs:label ?mista . \
                        ?b ccts:hasAssociatedObjectClass ?oTerm. \
                        FILTER (?str = '"+etsitaan+u"') \
                        FILTER (?mista = '"+mista+u"')}"

        sparql = SPARQLWrapper(u"http://sosmeta.fi:8080/openrdf-sesame/repositories/sosmeta")

        sparql.setQuery(queryString)
        sparql.setMethod(POST)
        sparql.setReturnFormat(XML)
        results = sparql.query().convert()

        for elem in results.getElementsByTagName(u'boolean'):
            child = elem.firstChild
            if child:
                if(child.nodeValue == u"true"):
                    return True
                else:
                    return False

                
                #koon tyhjien kenttien sisällön.
def sisallonPaivitys(etsitaan, mista, mita, tagName, entryType):
    try:
        etsitaan = valinPoisto(etsitaan)#Poistaa ylimääräiset välilyönnit.
        etsitaan = sanaMuunnos(etsitaan)#Muuntaa annetun sanan ääkköset unicode-koodiksi.
        mista = valinPoisto(mista)#Poistaa ylimääräiset välilyönnit.
        mista = sanaMuunnos(mista)
    except:
        htmlLisays = (u"<h4 class='red'>Rivillä: "+str(rivi+1)+u", Havaittu virhe muutettaessa etsittavän kentän arvoa.</h4>")
        validointi(htmlLisays, handle)

    if(mista == None and (type(etsitaan) is float) == False):
        queryString = u"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \
                        PREFIX ccts: <http://tikesos.fi/ccts#> \
                        PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> \
                        PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \
                        select ?"+mita+u" WHERE { \
                        ?any rdfs:label '"+etsitaan+u"'^^xsd:string . \
                        ?any rdf:type ccts:ABIE . \
                        ?any ccts:"+mita+u" ?"+mita+u" }"

        sparql = SPARQLWrapper(u"http://sosmeta.fi:8080/openrdf-sesame/repositories/sosmeta")

        sparql.setQuery(queryString)
        sparql.setMethod(POST)
        sparql.setReturnFormat(XML)
        results = sparql.query().convert()

        for elem in results.getElementsByTagName(tagName):
           child = elem.firstChild
           return child.nodeValue
    
    elif(entryType == 'ASBIE' and mista != None and etsitaan != None and (type(etsitaan) is float) == False):
##        print etsitaan+"."+mista+
        queryString = u"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \
                        PREFIX ccts: <http://tikesos.fi/ccts#> \
                        PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> \
                        PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \
                        select ?"+mita+u" WHERE { \
                        ?any rdfs:label '"+etsitaan+u"'^^xsd:string . \
                        ?any rdf:type ccts:ASBIE . \
                        ?any ccts:hasObjectClassTerm ?abie . \
                        ?abie rdf:type ccts:ABIE .\
                        ?abie rdfs:label '"+mista+u"'^^xsd:string . \
                        ?any ccts:"+mita+u" ?"+mita+u" }"


        sparql = SPARQLWrapper(u"http://sosmeta.fi:8080/openrdf-sesame/repositories/sosmeta")

        sparql.setQuery(queryString)
        sparql.setMethod(POST)
        sparql.setReturnFormat(XML)
        results = sparql.query().convert()

        for elem in results.getElementsByTagName(tagName):
           child = elem.firstChild
           return child.nodeValue

    elif((type(etsitaan) is float) == False  and mista != None and entryType == 'BBIE' and onkoLuokka(mista) == True and etsitaan != None):
        queryString = u"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \
                        PREFIX ccts: <http://tikesos.fi/ccts#> \
                        PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> \
                        PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \
                        select ?"+mita+u" WHERE { \
                        ?any rdfs:label '"+mista+u"'^^xsd:string . \
                        ?any rdf:type ccts:ABIE . \
                        ?any ccts:hasObjectClassTerm ?oTerm . \
                        ?bbie ccts:hasObjectClassTerm ?oTerm . \
                        ?bbie rdf:type ccts:BBIE . \
                        ?bbie rdfs:label '"+etsitaan+u"'^^xsd:string . \
                        ?bbie ccts:"+mita+u" ?"+mita+u" }"

        sparql = SPARQLWrapper(u"http://sosmeta.fi:8080/openrdf-sesame/repositories/sosmeta")

        sparql.setQuery(queryString)
        sparql.setMethod(POST)
        sparql.setReturnFormat(XML)
        results = sparql.query().convert()

        for elem in results.getElementsByTagName(tagName):
           child = elem.firstChild
           return child.nodeValue
        
    elif(mista != None and entryType == 'BBIE' and etsitaan != None and (type(etsitaan) is float) == False):
       # print mista+"-"+mita+"-"+etsitaan+"-"+tagName
        queryString = u"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \
                        PREFIX ccts: <http://tikesos.fi/ccts#> \
                        PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> \
                        PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \
                        select ?"+mita+u" WHERE { \
                        ?any rdfs:label '"+mista+u"'^^xsd:string . \
                        ?any rdf:type ccts:ASBIE . \
                        ?any ccts:hasAssociatedObjectClass ?aClass . \
                        ?bbie ccts:hasObjectClassTerm ?aClass . \
                        ?bbie rdf:type ccts:BBIE . \
                        ?bbie rdfs:label '"+etsitaan+u"'^^xsd:string . \
                        ?bbie ccts:"+mita+u" ?"+mita+u" }"

        sparql = SPARQLWrapper(u"http://sosmeta.fi:8080/openrdf-sesame/repositories/sosmeta")

        sparql.setQuery(queryString)
        sparql.setMethod(POST)
        sparql.setReturnFormat(XML)
        results = sparql.query().convert()

        for elem in results.getElementsByTagName(tagName):
           child = elem.firstChild
           return child.nodeValue
        
##    elif(entryType == 'BBIE' and mista != None and etsitaan != None and (type(etsitaan) is float) == False):
####        print etsitaan+"."+mista
##        queryString = u"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \
##                        PREFIX ccts: <http://tikesos.fi/ccts#> \
##                        PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> \
##                        PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \
##                        select ?"+mita+u" WHERE { \
##                        ?any rdfs:label '"+etsitaan+u"'^^xsd:string . \
##                        ?any rdf:type ccts:BBIE . \
##                        ?any ccts:hasObjectClassTerm ?upper . \
##                        ?upper rdfs:label '"+mista+u"'^^xsd:string . \
##                        ?any ccts:"+mita+u" ?"+mita+u" }"
##
##        sparql = SPARQLWrapper(u"http://sosmeta.fi:8080/openrdf-sesame/repositories/sosmeta")
##
##        sparql.setQuery(queryString)
##        sparql.setMethod(POST)
##        sparql.setReturnFormat(XML)
##        results = sparql.query().convert()
##
##        for elem in results.getElementsByTagName(tagName):
##           child = elem.firstChild
##           return child.nodeValue


##    elif(tagName != None):
##        queryString = u"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \
##                        PREFIX ccts: <http://tikesos.fi/ccts#> \
##                        PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> \
##                        PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \
##                        select ?"+mita+u" WHERE { \
##                        ?any rdfs:label '"+etsitaan+u"'^^xsd:string . \
##                        ?any ccts:hasObjectClassTerm ?upper . \
##                        ?upper rdfs:label '"+mista+u"'^^xsd:string . \
##                        ?any ccts:"+mita+u" ?"+mita+u" }"
##
##        sparql = SPARQLWrapper(u"http://sosmeta.fi:8080/openrdf-sesame/repositories/sosmeta")
##
##        sparql.setQuery(queryString)
##        sparql.setMethod(POST)
##        sparql.setReturnFormat(XML)
##        results = sparql.query().convert()
##
##        for elem in results.getElementsByTagName(tagName):
##           child = elem.firstChild
##           return child.nodeValue

##Poistaa välilyönnit ja muuntaa jokaisen sanan ensimmäisen kirjaimen isoksi
def valitpois(string):
    uusistring = ""
    string = string.replace("-", " ")
    taulu = string.split()
    for i in range(0, len(taulu)):
        isoksi = taulu[i].capitalize()
        uusistring += isoksi
    return uusistring

##Muuntaa sanan ääkköset aakkosiksi
def aakkosiksi(string):
    string = string.replace(u"ä", "a")
    string = string.replace(u"ö", "o")
    string = string.replace(u"å", "a")
    return string

##Muuntaa sanan ääkköset aakkosiksi
def xmlSafe(string):
    string = string.replace(u"<", "(")
    string = string.replace(u">", ")")
    return string

##Tutkii mistä sarakkeesta löytyy "Määritelmä"-teksti.
def maaritelmaTarkistus(ws):
    sarake = 0
    rivi = 1
    lopetus = u"Määritelmä"
    ruutu = ws.cell(row = rivi, column = sarake)

    while(ruutu.value != lopetus and rivi < 10):
        ruutu = ws.cell(row = rivi, column = sarake)
        sarake +=1
        if(sarake >= 30):
            sarake = 0
            rivi += 1
    
    if(rivi >= 10):
        return -1
    else:
        sarake -= 1
        return sarake

##Tutkii mistä sarakkeesta löytyy "Esimerkki"-teksti.
def esimerkkiTarkistus(ws):
    sarake = 0
    rivi = 1
    lopetus = "Esimerkki"
    ruutu = ws.cell(row = rivi, column = sarake)

    while(ruutu.value != lopetus and rivi < 10):
        ruutu = ws.cell(row = rivi, column = sarake)
        sarake +=1
        if(sarake >= 30):
            sarake = 0
            rivi += 1
    
    if(rivi >= 10):
        return -1
    else:
        sarake -= 1
        return sarake

##Tutkii mistä sarakkeesta löytyy "Huomautus"-teksti.
def huomautusTarkistus(ws):
    sarake = 0
    rivi = 1
    lopetus = "Huomautus"
    ruutu = ws.cell(row = rivi, column = sarake)

    while(ruutu.value != lopetus and rivi < 10):
        ruutu = ws.cell(row = rivi, column = sarake)
        sarake +=1
        if(sarake >= 30):
            sarake = 0
            rivi += 1
    
    if(rivi >= 10):
        return -1
    else:
        sarake -= 1
        return sarake

####Tutkii mistä sarakkeesta löytyy "Dokumentaatio"-teksti.
##def dokumentaatioTarkistus(ws):
##    sarake = 0
##    rivi = 1
##    lopetus = "Dokumentaatio"
##    ruutu = ws.cell(row = rivi, column = sarake)
##
##    while(ruutu.value != lopetus and rivi < 10):
##        ruutu = ws.cell(row = rivi, column = sarake)
##        sarake +=1
##        if(sarake >= 30):
##            sarake = 0
##            rivi += 1
##    
##    if(rivi >= 10):
##        return -1
##    else:
##        sarake -= 1
##        return sarake

##Tutkii mistä sarakkeesta löytyy "Tiedon esitysmuoto"-teksti.
def tiedonEsitysmuotoTarkistus(ws):
    sarake = 0
    rivi = 1
    lopetus = "Tiedon esitysmuoto"
    ruutu = ws.cell(row = rivi, column = sarake)

    while(ruutu.value != lopetus and rivi < 10):
        ruutu = ws.cell(row = rivi, column = sarake)
        sarake +=1
        if(sarake >= 30):
            sarake = 0
            rivi += 1
    if(rivi >= 10):
        return -1
    else:
        sarake -= 1
        return sarake

##Tutkii mistä sarakkeesta löytyy "Toistuva"-teksti.
def toistuvaTarkistus(ws):
    sarake = 0
    rivi = 1
    lopetus = "Toistuva"
    ruutu = ws.cell(row = rivi, column = sarake)

    while(ruutu.value != lopetus and rivi < 10):
        ruutu = ws.cell(row = rivi, column = sarake)
        sarake +=1
        if(sarake >= 30):
            sarake = 0
            rivi += 1
    
    if(rivi >= 10):
        return -1
    else:
        sarake -= 1
        return sarake

##Tutkii mistä sarakkeesta löytyy "Pakollinen"-teksti.
def pakollinenTarkistus(ws):
    sarake = 0
    rivi = 1
    lopetus = "Pakollinen"
    ruutu = ws.cell(row = rivi, column = sarake)
    oletus = 15

    while(ruutu.value != lopetus and rivi < 10):
        ruutu = ws.cell(row = rivi, column = sarake)
        sarake +=1
        if(sarake >= 30):
            sarake = 0
            rivi += 1

    if(rivi >= 10):
        return -1
    else:
        sarake -= 1
        return sarake

####Tulostaa pinon
##def tulostaLista(lista):
##    for i in lista:
##        for j in i.values():
##            for e in j:
##                print i.keys(), e

##Etsii taulukosta määrätyillä arvoilla viimeisen rivin
def viimeinenRiviTaulukossa(ws):
    rivi = 0
    etsittava = "Versiohistoria"
    etsittava2 = "Versiohistoria:"

    try:
        while(ws.cell(row = rivi, column = 0).value != etsittava and ws.cell(row = rivi, column = 0).value != etsittava2):
            rivi += 1
            if(rivi >= 1000):
                print "Versiohistoria-kenttää ei löydy!"
                raise ValueError
    except ValueError:
        rivi = 0
        try:
            while((type(ws.cell(row = rivi, column = 0).value) is float) == False):
                rivi += 1
                if(rivi >= 1000):
                    print "Versiohistorian numerointia ei löytynyt ensimmäisestä sarakkeesta!"
                    raise TypeError
        except TypeError:
            rivi = 0
            try:
                while((type(ws.cell(row = rivi, column = 1).value) is float) == False):
                    rivi += 1
                    if(rivi >= 1000):
                        raise NameError
            except NameError:
                print "Versiohistorian numerointia ei löydy!"

    tiedonesitysmuoto = tiedonEsitysmuotoTarkistus(ws)
    tyhjarivi = True
    while(tyhjarivi == True):
        rivi -= 1
        sarake = 0
        for sarake in range(0, tiedonesitysmuoto):
            if(ws.cell(row = rivi, column = sarake).value != None):
                tyhjarivi = False
    return rivi

##Muuntaa annetun sanan ääkköset unicode-koodiksi
def sanaMuunnos(string):
    if(string != None):
        string = string.replace(u'ä', '\u00E4')
        string = string.replace(u'ö', '\u00F6')
        return string

##poistaa ylimääräiset välit
def valinPoisto(string):
    if(string != None):
        muunnettu = ""
        taulu = string.split()
        for i in range(0, len(taulu)):
            muunnettu += taulu[i]+" "
        string = muunnettu.strip()
    return string


main()
